#include "splitmerge.h"

SplitMerge::SplitMerge()
{

}

SplitMerge::SplitMerge(int seuilSplit, int seuilMerge, QString file, bool color)
{

    std::cout<<"Coucou 0 "<<std::endl;

    IplImage *mainImg;
    if (color)
    {
        mainImg = cvLoadImage(file);
    }
    else
    {
        mainImg = cvLoadImage(file, CV_LOAD_IMAGE_GRAYSCALE);
    }
    IplImage *splitImg = cvCloneImage(mainImg);
    IplImage *mergeImg;

    if (color)
    {
        mergeImg = cvCreateImage(cvSize(mainImg->width, mainImg->height), IPL_DEPTH_8U, 3);
    }
    else
    {
        mergeImg = cvCreateImage(cvSize(mainImg->width, mainImg->height), IPL_DEPTH_8U, 1);
    }

    Node *root = new Node(0, 0, splitImg->width - 1, splitImg->height - 1, 0, NULL);
    Quadtree *quad = new Quadtree(root);


    Split(quad, splitImg, seuilSplit, color);
    Merge(quad, mainImg, mergeImg, seuilMerge);



    cvNamedWindow("Split", CV_WINDOW_AUTOSIZE);
    cvShowImage("Split", splitImg);
    //cvSaveImage("Split.jpg", splitImg);
    //cvWaitKey(0);

    cvNamedWindow("Merge", CV_WINDOW_AUTOSIZE);
    cvShowImage("Merge", mergeImg);
    //cvSaveImage("Merge.jpg", mergeImg);

    cvWaitKey(0);
    cvWaitKey(0);

    cvDestroyWindow("Split");
    cvReleaseImage(&splitImg);

    cvDestroyWindow("Merge");
    cvReleaseImage(&mergeImg);
    delete(quad);
    
    img = mergeImg;
    //return mergeImg;
}



void SplitMerge::Split(Quadtree *quad, IplImage *img, int seuil, bool isColorImg)
{
        const std::vector<Node*>& allNode = quad->GetAllNode();

        int i = 0;
        bool run = true;
        while (run)
        {
                run = false;
                int maxLevel = allNode.back()->GetNodeLevel();

                std::vector<Node*>::const_reverse_iterator rIt = allNode.rbegin();
                size_t pos =  allNode.size();
                while (rIt != allNode.rend() && (*rIt)->GetNodeLevel() == maxLevel)
                {
                        ++rIt;
                        pos--;
                }

                size_t stop = allNode.size();
                i = 1;
                for ( size_t j = pos ; j < stop; j++)
                {
                        //std::cout << i << " : ";
                        if (!(allNode.at(j)->IsHomogeneous(img, seuil, isColorImg)))
                        {
                                quad->AddNode(allNode.at(j));
                                run = true;
                        }
                        i++;
                }
        }

        quad->Display(img);
}

void SplitMerge::Merge(Quadtree *quad, IplImage *imgSplit, IplImage *imgMerge, int seuil)
{
        std::cout<< "Merge debut "<< std::endl;

        const std::vector<Node*>& allNode = quad->GetAllNode();
        std::vector<Node*>::const_reverse_iterator rIt;
        for (rIt = allNode.rbegin(); rIt != allNode.rend(); ++rIt)
        {
                if ((*rIt)->GetColored() == false)
                {
                        int averageMaxBlue = (*rIt)->GetColorAverage() + seuil;
                        int averageMinBlue = (*rIt)->GetColorAverage() - seuil;
                        if (averageMaxBlue > 255)
                                averageMaxBlue = 255;
                        if (averageMinBlue < 0)
                                averageMinBlue = 0;

                        /*CvScalar pixel;
                        for (int i = 0 ; i < 3; i++)
                        {
                                pixel.val[i] = rand()%255;
                        }*/

                        CvScalar pixel;

                        if ((*rIt)->GetColorAverageBlue() != -1)
                        {
                                pixel.val[0] = (*rIt)->GetColorAverageBlue();
                                pixel.val[1] = (*rIt)->GetColorAverageGreen();
                                pixel.val[2] = (*rIt)->GetColorAverageRed();

                                int averageMaxGreen = (*rIt)->GetColorAverageGreen() + seuil;
                                int averageMinGreen = (*rIt)->GetColorAverageGreen() - seuil;
                                if (averageMaxGreen > 255)
                                        averageMaxGreen = 255;
                                if (averageMinGreen < 0)
                                        averageMinGreen = 0;

                                int averageMaxRed = (*rIt)->GetColorAverageRed() + seuil;
                                int averageMinRed = (*rIt)->GetColorAverageRed() - seuil;
                                if (averageMaxRed > 255)
                                        averageMaxRed = 255;
                                if (averageMinRed < 0)
                                        averageMinRed = 0;

                                int averageMax = (averageMaxGreen + averageMaxRed + averageMaxBlue) / 3;
                                int averageMin = (averageMinGreen + averageMinRed + averageMinBlue) / 3;

                                (*rIt)->ColorNode(imgMerge, pixel, averageMax, averageMin);
                        }
                        else
                        {
                                pixel.val[0] = (*rIt)->GetColorAverage();
                                (*rIt)->ColorNode(imgMerge, pixel, averageMaxBlue, averageMinBlue);
                        }
                }
        }

        //std::cout<< "Merge fin"<< std::endl;
}
